/**
 * 
 */
const version = "15.0.12";
 
const $loadingElem = document.querySelector('#loading');
const $mainElem = document.querySelector('#main');
const $markdownElem = document.querySelector('#markdown'); 
  
const $responseTimeElem = document.querySelector('#responseTime');
const $previewElem = document.querySelector('#preview');
const $previewIframe = document.querySelector('#preview iframe'); 
const $help = document.querySelector("#help")
    
let lastInput = '';
let inputDirty = true;
let $activeOutputElem = null;
  
let delayTime = 1;
let checkChangeTimeout = null;
let markedWorker = null;
 
$previewIframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms');
$previewIframe.setAttribute('src', ''); //必须设置src为空 否则不会生效。 
$previewIframe.addEventListener('load', handleIframeLoad);
  
$markdownElem.addEventListener('change', handleInput, false);
$markdownElem.addEventListener('keyup', handleInput, false);
$markdownElem.addEventListener('keypress', handleInput, false);
$markdownElem.addEventListener('keydown', handleInput, false);
   
$help.addEventListener('click',function(){alert('help')},false);


Promise.all([
   Initial()
]).then(() => { 
  inputDirty = false;
  doWork();
  setScrollPercent(0);
   
  $loadingElem.style.display = 'none';
  $mainElem.style.display = 'block'; 

}).catch((err) => {
   console.error('loading Error',err);
   $loadingElem.classList.add('loadingError');
   $loadingElem.textContent = 'Failed to load marked. Refresh the page to try again.';

});
 
function Initial()
{
     //获取md 源码
    function MarkdownEditor()
    {
        this.state={};
        this.on = function(){}
        this.previewing = function(){}
        this.getMarkdown = function(){return $markdownElem.value;}
        this.getHTML = function(){return  $previewIframe.contentDocument.body.innerHTML;}
    }
    window.mdEditor = new MarkdownEditor(); 

    mermaid.initialize({
      startOnLoad: false, //true:自动开始渲染页面上所有的 <pre class="mermaid">图形代码</pre> 图表块
      theme: 'forest', //设置主题为暗色主题,支持 default、forest、dark  ,neutral ,base(这是唯一可以修改的主题) 文档 https://mermaid.nodejs.cn/config/theming.html
      flowchart: {
        curve: 'cardinal'//可选 linear（直线）、curve（贝塞尔曲线）、cardinal（折线）。
      },
      sequence: {
        actorMargin: 50//‌时序图参与者间距‌,调整参与者之间的间隔
      },
      fontFamily:'"Microsoft YaHei", sans-serif',
      securityLevel:'strict',//'strict'（默认）:单击功能被禁用、'antiscript':启用单击功能、'loose':允许文本中包含 HTML 标签，并启用单击功能、'sandbox':所有渲染都在沙盒 iframe 中进
      maxTextSize:10000
    }); 
     
    //console.debug('添加一个mermaid renderer，用于支持流程图'); 

    const renderer = new marked.Renderer();
    renderer.code = function(data) {
       //console.log('code',arguments);
       var _html_code = ""
       if (data.lang === 'mermaid') { 
          
        var _chart_id = "rsd_chart_" + Date.now();
        //图标容器
         _html_code = `<div id="${_chart_id}" style="color:red;" class="mermaid">{正在生成图形...}</div>`;
         mermaidRender(_chart_id +"_svg", data.text)
         .then(function(resp){

          //console.log(resp);
           //输出 SVG 代码，
           var svg_code = resp.svg;
           var diagramType = resp.diagramType;
           //var  bindFunctions = resp.bindFunctions;
           //预览页面在iframe中，对接到外部 处理
           if( mdEditor.onRender)
           {
              mdEditor.onRender(_chart_id,data.lang,diagramType,svg_code);
           }
           
         })
         .catch(function(err){
             console.error(err);
         }); 
      }
      else
      {
        _html_code = data.text;
      }
      //console.log('_html_code',_html_code);

      return _html_code; // 默认处理
    };
    
    const highlight = function(code, type) {
        console.log('high-light',type);
        if (type === 'mermaid') {
           var _chart_id = "rsd_chart_" + Date.now();
          mermaid.render(_chart_id, code)
          .then(
            function (resp) { 
                //console.log(resp);
                //输出 SVG 代码，
                var svg_code = resp.svg;
                var diagramType = resp.diagramType;
                //var bindFunctions = resp.bindFunctions;
                document.getElementById(_chart_id).innerHTML = svg_code; 
            })
            .catch(function (err) {
                console.error(err);
            }
        )
        .catch(function (err) {
                console.error(err);
            });

          return `<div class="mermaid" id='mermaid-${this.count}'>${code}</div>`;
        }

        return hljs.highlightAuto(code).value;
      }

      const options = {
        "renderer":renderer,
        "highlight":highlight,
        "async": false,
        "breaks": false,
        "extensions": null,
        "gfm": true,
        "hooks": null,
        "pedantic": false,
        "silent": false,
        "tokenizer": null,
        "walkTokens": null
    }; 
    marked.setOptions(options);

}

async function mermaidRender(id,md_code)
{
  
  try {
    var rs = await mermaid.parse(md_code, { suppressErrors: false });
    if (!rs) {
      svg_code = 'mermaid Error';
    }
  }
  catch (err) {
    svg_code = err.message;
  }

  return await mermaid.render(id, md_code); 
        
}

function handleIframeLoad() {
  lastInput = '';
  inputDirty = true;
}

function handleInput() {
  inputDirty = false;
  doWork(); 
}

function getScrollSize() {
  if (!$activeOutputElem) {
    return 0;
  }

  const e = $activeOutputElem;

  return e.scrollHeight - e.clientHeight;
}

function getScrollPercent() {
  if (!$activeOutputElem) {
    return 1;
  }

  const size = getScrollSize();

  if (size <= 0) {
    return 1;
  }

  return $activeOutputElem.scrollTop / size;
}

function setScrollPercent(percent) {
  if ($activeOutputElem) {
    $activeOutputElem.scrollTop = percent * getScrollSize();
  }
}

function doWork() {
    if (inputDirty) {
        inputDirty = false; 
        return;
    }
     
    const markdown = $markdownElem.value;
    const hash = version + markdown ;//+ JSON.stringify(options);
   
    if (lastInput !== hash) {
        lastInput = hash;
        delayTime = 100;

        const startTime = new Date();                                                                            
        const lexed = marked.lexer(markdown);//,options
        //const lexedList = jsonString(lexed);  //内部使用的标签，可以用于生成文档目录结构
        //console.log(lexedList); 
        const parsed = marked.parser(lexed);//,options
        const endTime = new Date();
        const scrollPercent = getScrollPercent();
        setParsed(parsed);
        setScrollPercent(scrollPercent);
        setResponseTime(endTime - startTime);
        clearTimeout(checkChangeTimeout);
        delayTime = 10;
    }

    checkChangeTimeout = window.setTimeout(doWork, delayTime);
}

function setResponseTime(ms) {
  let amount = ms;
  let suffix = 'ms';
  if (ms > 1000 * 60 * 60) {
    amount = 'Too Long';
    suffix = '';
  } else if (ms > 1000 * 60) {
    amount = '>' + Math.floor(ms / (1000 * 60));
    suffix = 'm';
  } else if (ms > 1000) {
    amount = '>' + Math.floor(ms / 1000);
    suffix = 's';
  }
  $responseTimeElem.textContent = amount + suffix;
  $responseTimeElem.animate([
    { transform: 'scale(1.2)' },
    { transform: 'scale(1)' },
  ], 200);
}

function setParsed(parsed) {
    //console.log(parsed);
  if($previewIframe && $previewIframe.contentDocument && $previewIframe.contentDocument.body)
  {
    try {
      $previewIframe.contentDocument.body.innerHTML = parsed;
    }
    catch (err) {
      console.log(err);
    }
  } 
  
}

/**
 * 
 * @param {*} input 
 * @param {*} level 
 * @returns 
 */
function jsonString(input, level) {
  level = level || 0;
  if (Array.isArray(input)) {
    if (input.length === 0) {
      return '[]';
    }
    const items = [];
    let i;
    if (!Array.isArray(input[0]) && typeof input[0] === 'object' && input[0] !== null) {
      for (i = 0; i < input.length; i++) {
        items.push(' '.repeat(2 * level) + jsonString(input[i], level + 1));
      }
      return '[\n' + items.join('\n') + '\n]';
    }
    for (i = 0; i < input.length; i++) {
      items.push(jsonString(input[i], level));
    }
    return '[' + items.join(', ') + ']';
  } else if (typeof input === 'object' && input !== null) {
    const props = [];
    for (const prop in input) {
      props.push(prop + ':' + jsonString(input[prop], level));
    }
    return '{' + props.join(', ') + '}';
  } else {
    return JSON.stringify(input);
  }
}
 /**
  * 
  * @param {*} mdStr 
  */
function render(mdStr)
{
    //console.error(mdStr);
    $markdownElem.value = mdStr;
    inputDirty = false;
    doWork();
}


/**
 * 
 * @param {*} e 
 */
document.onreadystatechange = function (e) {
    //console.log(e);
    // const message = document.readyState + " from editor.html!";
    // const targetOrigin = "*"; // 可以指定父页面的源，例如 "http://example.com"
    // window.parent.postMessage(message, targetOrigin);
   //
   if(document.readyState == 'complete')
   {
        window.run();
   }
    
}
